﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace BookStore
{
    public class cTcp
    {
        public TcpClient Client{ get; private set; }
        public Stream Stream;
        public StreamReader Reader;
        public StreamWriter Writer;
        public Thread Thread;

        public delegate void DataCarrier(string data);
        public event DataCarrier OnDataRecieved;
        
        public delegate void LoginStatus(string data);
        public event LoginStatus LoginStatusRecieved;

        public delegate void RegisterStatus(string data);
        public event RegisterStatus RegisterStatusRecieved;

        public delegate void ResetStatus(string data);
        public event ResetStatus RestStatusRecieved;
        
        public delegate void DisconnectNotify();
        public event DisconnectNotify OnDisconnect;

        public delegate void ErrorCarrier(Exception e);
        public event ErrorCarrier OnError;

        public bool flag = false;
        public bool Connecter(string ip, int port)
        {
            try
            {
                Client = new TcpClient();
                Client.Connect(IPAddress.Parse(ip), port);
                Stream = Client.GetStream();
                Writer = new StreamWriter(Stream);
                Thread = new Thread(ReadContent);
                Thread.Start();
            }
            catch (Exception e)
            {
                if (OnError != null)
                    OnError(e);
                return false;
            }
            return true;
        }

        private void ReadContent()
        {
            var r = new StreamReader(Stream);
            var buffer = new List<int>();
            while (!flag)
            {
                try
                {
                    if (r.EndOfStream)
                        break;
                    int charCode = r.Read();
                    if (charCode == -1)
                        break;
                    if (charCode != 0)
                    {
                        buffer.Add(charCode);
                        continue;
                    }
                    if (OnDataRecieved != null)
                    {
                        var chars = new char[buffer.Count];
                        for (int i = 0; i < buffer.Count; i++)
                        {
                            chars[i] = Convert.ToChar(buffer[i]);
                        }
                        var message = new string(chars);
                        //OnDataRecieved(message);
                        if(message == "result:FAILED" || message == "result:LOGIN_OK")
                            LoginStatusRecieved(message);
                        else if(message == "result:SAME" || message == "result:REGISTER_OK")
                            RegisterStatusRecieved(message);
                        else
                            RestStatusRecieved(message);
                    }
                    buffer.Clear();
                }
                catch (Exception e)
                {
                    if (OnError != null)
                    {
                        OnError(e);
                        break;
                    }
                    break;
                }

            }
            if (OnDisconnect != null)
                OnDisconnect();
        }

        private void WriteMessages(string m)
        {
            try
            {
                Writer.Write(m + "\0");
                Writer.Flush();  
            }
            catch (Exception e)
            {
                if (OnError != null)
                    OnError(e);
            }
        }

        public void WriteData(data d)
        {
            WriteMessages(d);
        }
    }
}
